package kt.com.bilin.coin.utils

import android.app.Activity
import android.content.Context
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.lifecycleScope
import com.bilin.coin.ApiConstant
import com.bilin.coin.R
import com.yanzhenjie.album.Album
import com.yanzhenjie.album.AlbumFile
import com.yanzhenjie.album.api.widget.Widget
import kotlinx.coroutines.CoroutineScope
import kt.com.bilin.coin.api.ApiRequest
import kt.com.bilin.coin.bean.ImageUploadBean
import kt.com.bilin.coin.bean.UploadDataBean
import kt.com.bilin.coin.common.toColor
import kt.com.bilin.coin.common.toastMessageLong
import kt.com.bilin.coin.ui.dialog.LoadingDialog
import kt.com.bilin.coin.ui.dialog.safeDismissDialog
import kt.com.bilin.coin.ui.dialog.safeShowDialog
import kt.com.bilin.coin.viewmodel.BackgroundCommonApi
import top.zibin.luban.Luban
import java.util.*

typealias onUploadSuccessListener = ((MutableList<ImageUploadBean>) -> Unit)?
typealias onCancelSuccessListener = (() -> Unit)?

class ImageUploadUtils : LifecycleObserver {
    companion object {
        private val MIME_TYPE = mutableListOf("image/jpg", "image/jpeg", "image/png", "image/JPG", "image/JPEG", "image/PNG")
//        private const val MIN_SIZE = 50 * 1024.toLong()
    }

    constructor(activity: FragmentActivity, path: String, mOnUploadSuccessListener: onUploadSuccessListener) : super() {
        activity.lifecycle.addObserver(this)
        this.path = path
        this.activity = activity
        this.mOnUploadSuccessListener = mOnUploadSuccessListener
        initView()
    }

    constructor(fragment: Fragment, path: String, mOnUploadSuccessListener: onUploadSuccessListener) : super() {
        fragment.lifecycle.addObserver(this)
        this.path = path
        this.fragment = fragment
        this.mOnUploadSuccessListener = mOnUploadSuccessListener
        initView()
    }

    private var activity: FragmentActivity? = null
    private var fragment: Fragment? = null
    private var path: String
    private var mLoadingDialog: LoadingDialog? = null
    private lateinit var mWidget: Widget
    private lateinit var mBuilder: ImageUploadUBuilder
    private var mOnUploadSuccessListener: onUploadSuccessListener = null
    var mOnCancelSuccessListener: onCancelSuccessListener = null
    private fun initView() {
        getActivity()?.let {
            mLoadingDialog = LoadingDialog(it)
            mLoadingDialog?.setCancelable(false)
            mWidget = Widget.newDarkBuilder(it)
                    .statusBarColor(R.color.main_color.toColor())
                    .toolBarColor(R.color.main_color.toColor())
                    .bucketItemCheckSelector(R.color.text_hint_color_2.toColor(), R.color.main_color.toColor())
                    .mediaItemCheckSelector(R.color.text_hint_color_2.toColor(), R.color.main_color.toColor())
                    .build()
        }
    }

    fun selectImage(builder: ImageUploadUBuilder) {
        mBuilder = builder
        mLoadingDialog?.safeShowDialog()
        val content = getContext() ?: return
        if (mBuilder.isMultipleChoice) {
            Album.image(content)
                    .multipleChoice()
                    .selectCount(mBuilder.selectCount)
                    .afterFilterVisibility(false)
                    .camera(true)
                    .columnCount(mBuilder.columnCount)
                    .filterMimeType { attributes: String? -> !MIME_TYPE.contains(attributes) }
//                    .filterSize { attributes: Long -> attributes < MIN_SIZE }
                    .widget(mWidget)
                    .onResult(this::onAction)
                    .onCancel(this::onCancel)
                    .start()
        } else {
            Album.image(content)
                    .singleChoice()
                    .afterFilterVisibility(false)
                    .camera(true)
                    .columnCount(mBuilder.columnCount)
                    .filterMimeType { attributes: String? -> !MIME_TYPE.contains(attributes) }
//                    .filterSize { attributes: Long -> attributes < MIN_SIZE }
                    .widget(mWidget)
                    .onResult(this::onAction)
                    .onCancel(this::onCancel)
                    .start()
        }
    }

    fun onAction(result: ArrayList<AlbumFile>) {
        if (result.isNotEmpty()) {
            val srcPaths = mutableListOf<UploadDataBean>()
            result.forEach { srcPaths.add(UploadDataBean(it.path, it.path)) }
            if (mBuilder.isCompress) { // 是否压缩
                val compressPaths = mutableListOf<String>()
                result.forEach { compressPaths.add(it.path) }
                val coroutineScope = getCoroutineScope()
                if (coroutineScope != null) {
                    ApiRequest(coroutineScope).launchUI({
                        Luban.with(getActivity())
                                .ignoreBy(100)
                                .setFocusAlpha(true)
                                .load(compressPaths)
                                .get()
                                .forEachIndexed { index, file -> srcPaths[index].compressFile = file.path }
                        doAction(srcPaths)
                    }, error = {
                        "压缩失败".toastMessageLong()
                        mLoadingDialog?.safeDismissDialog()
                    })
                }
            } else doAction(srcPaths)
        }
    }

    fun doAction(result: MutableList<UploadDataBean>) {
        if (mBuilder.isUp) {
            if (mBuilder.isMultipleChoice) {
                handFile(result)
            } else {
                if (mBuilder.cutOut) { // 开启剪裁
//                    cutOut(result[0])
                } else {
                    handFile(result)
                }
            }
        } else {
            mLoadingDialog?.safeDismissDialog()
            val imageUploads = mutableListOf<ImageUploadBean>()
            result.forEach {
                val mImageUploadBean = ImageUploadBean(filePath = it.compressFile, originalFile = it.originalFile)
                imageUploads.add(mImageUploadBean)
            }
            mOnUploadSuccessListener?.invoke(imageUploads)
        }
    }

    private fun onCancel(result: String) {
        mOnCancelSuccessListener?.invoke()
        mLoadingDialog?.safeDismissDialog()
    }

    private fun handFile(result: MutableList<UploadDataBean>) {
        val coroutineScope = getCoroutineScope()
        if (coroutineScope != null) {
            mLoadingDialog?.safeShowDialog()
            BackgroundCommonApi.uploadFile(coroutineScope, result, path, mLoadingDialog) {
                it?.let { mOnUploadSuccessListener?.invoke(mutableListOf(ImageUploadBean(url = it, netUrl = ApiConstant.OSSURL + it))) }
                mLoadingDialog?.safeDismissDialog()
            }
        } else {
            mLoadingDialog?.safeDismissDialog()
        }
    }

    private fun getCoroutineScope(): CoroutineScope? = when {
        activity != null -> activity?.lifecycleScope
        fragment != null -> fragment?.lifecycleScope
        else -> null
    }

    fun gallery(gallery: List<String>, currentPosition: Int) {
        gallery(ArrayList(gallery), currentPosition)
    }

    fun gallery(gallery: ArrayList<String>, currentPosition: Int) {
        val content = getContext() ?: return
        Album.gallery(content)
                .currentPosition(currentPosition)
                .checkedList(gallery)
                .checkable(false)
                .widget(
                        Widget.newDarkBuilder(content)
                                .statusBarColor(ContextCompat.getColor(content, R.color.main_color))
                                .toolBarColor(ContextCompat.getColor(content, R.color.main_color))
                                .title(R.string.text_preview)
                                .build()
                )
                .start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private fun onDestroy() {
        activity?.lifecycle?.removeObserver(this)
        fragment?.lifecycle?.removeObserver(this)
        activity = null
        fragment = null
        mOnUploadSuccessListener = null
        mLoadingDialog?.safeDismissDialog()
        mLoadingDialog = null
    }

    private fun getContext(): Context? = if (activity != null) activity else fragment?.context

    private fun getActivity(): Activity? = if (activity != null) activity else fragment?.activity
}

inline fun ImageUploadUtils.selectImage(imageUploadUBuilder: ImageUploadUBuilder.() -> Unit) {
    selectImage(ImageUploadUBuilder().also(imageUploadUBuilder))
}

class ImageUploadUBuilder {
    var cutOut = false
    var isMultipleChoice = false
    var isUp = true
    var isCompress = true
    var selectCount = 9
    var columnCount = 3
}

/*
class QcloudUpload(private val mOnFileUploadListener: OnFileUploadListener) {
    companion object {
        private var UPLOAD_MANAGER: UploadManager = UploadManager(
                Configuration.Builder()
                        .connectTimeout(10) // 链接超时。默认10秒
                        .useHttps(true) // 是否使用https上传域名
                        .responseTimeout(60) // 服务器响应超时。默认60秒
                        .zone(FixedZone.zone2) // 设置区域，不指定会自动选择。指定不同区域的上传域名、备用域名、备用IP。
                        .build(), 3
        )
        private var DOMAIN = ""
        private val FORMATTER = SimpleDateFormat("yyyyMMddHHmmssSSS")
    }

    private lateinit var cosPaths: MutableList<ImageUploadBean>
    private var srcPaths: MutableList<UploadDataBean> = mutableListOf()
    private var fileCount = 0
    private var mToken: String = ""
    private var isSign = false
    fun upload(srcPaths: MutableList<UploadDataBean>) {
        if (srcPaths.isEmpty()) return
        this.srcPaths = srcPaths
        mOnFileUploadListener.onStart()
        cosPaths = ArrayList<ImageUploadBean>()
        fileCount = srcPaths.size
        isSign = srcPaths.size == 1
        if (mToken.isEmpty()) {
            BackgroundCommonApi.getQiniuToken { qiNiuToken: String, domain: String ->
                if (qiNiuToken.isNotEmpty()) {
                    mToken = qiNiuToken
                    DOMAIN = domain
                    doUpload()
                } else mOnFileUploadListener.onFail(RuntimeException("获取token失败"))
            }
        } else doUpload()
    }

    private fun doUpload() {
        if (srcPaths.size < 1) return
        val data = srcPaths[0]
        val formatStr = FORMATTER.format(Date())
        val key = formatStr + "." + getFileExtension(data.compressFile)
        UPLOAD_MANAGER.put(
                data.compressFile, key, mToken, { key1, info, response ->
            Logger.e("info===>${info}")
            if (info.isOK) {
                try {
                    Logger.e("DOMAIN==>${DOMAIN}")
                    cosPaths.add(ImageUploadBean(filePath = data.compressFile, originalFile = data.originalFile, url = DOMAIN + key1))
                    srcPaths.removeAt(0)
                    if (!isSign) {
                        try {
                            mOnFileUploadListener.onPublishProgress(BigDecimal(cosPaths.size).divide(BigDecimal(fileCount), 2, RoundingMode.HALF_UP).multiply(BigDecimal(100)).toInt())
                        } catch (e: Exception) {
                            Logger.e(e)
                            mOnFileUploadListener.onFail(e)
                        }
                    }
                    if (srcPaths.size == 0) {
                        mOnFileUploadListener.onSuccess(cosPaths)
                        if (!isSign) mOnFileUploadListener.onPublishProgress(100)
                    } else doUpload()
                } catch (e: Exception) {
                    Logger.e(e)
                    mOnFileUploadListener.onFail(e)
                }
            } else mOnFileUploadListener.onFail(RuntimeException("上传失败"))
        }, UploadOptions(
                null, null, false,
                UpProgressHandler { key12: String?, percent: Double ->
                    if (isSign) {
                        try {
                            mOnFileUploadListener.onPublishProgress(BigDecimal(percent).multiply(BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toInt())
                        } catch (e: Exception) {
                            mOnFileUploadListener.onFail(e)
                        }
                    }
                }, null
        )
        )
    }

    fun getFileExtension(filePath: String): String? {
        if (isSpace(filePath)) return ""
        val lastPoi = filePath.lastIndexOf('.')
        val lastSep = filePath.lastIndexOf(File.separator)
        return if (lastPoi == -1 || lastSep >= lastPoi) "" else filePath.substring(lastPoi + 1)
    }

    private fun isSpace(s: String?): Boolean {
        if (s == null) return true
        var i = 0
        val len = s.length
        while (i < len) {
            if (!Character.isWhitespace(s[i])) {
                return false
            }
            ++i
        }
        return true
    }
}*/
